home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
DDJ0992.ARJ
/
DUNHAM.LS8
< prev
next >
Wrap
Text File
|
1992-04-20
|
32KB
|
930 lines
/* Listing #8: ibm.c signal handling & stack traceback */
#include <stdio.h>
#include <signal.h> /* for signal definitions */
#include <string.h> /* for strtok */
#include <a.out.h> /* to get COFF file header */
#include <sys/debug.h> /* to get tbtable */
/*----------------- local defines --------------------*/
#undef PROTOTYPES /* ignore prototype info */
#undef DEBUGPRINT /* we don't want debug info */
#define STACKDUMP 1 /* set to 1 to get 32bit stack dumps */
#define FRAMEDUMP 1 /* set to 1 to dump each stack frame */
#define PARAMDUMP 0 /* set to 1 to get parameter dumps */
#define LOCALSYMDUMP 0 /* set to 1 to get local symbol dumps */
#define JUMPPC 2 /* how to find next program counter */
#define JUMPSP 0 /* how to find next stack pointer */
#define PCADJUST 0x1000020a /* determined experimentally */
#define MAXLEVEL 40 /* maximum number of nested subroutine calls */
#define MAXPARAM 40 /* maximum number of subroutine parameters */
#define DUMPSIZE 256 /* size of stack dump */
#define NSIGNAL 31 /* #signals to describe in text array */
#define STREQ(a,b) (strcmp((a),(b))==0)
#define STRNEQ(a,b) (strcmp((a),(b))!=0)
#define CNULL '\0'
#ifdef PROTOTYPES
# define P_(s) s
#else
# define P_(s) ()
#endif
#ifdef DEBUGPRINT
# define DBPRINT(s) printf s
#else
# define DBPRINT(s)
#endif
/*----------------- external functions --------------------*/
char *malloc();
char *getenv();
/*----------------- internal functions --------------------*/
static void trb_exefind P_((int argc, char *argv));
static void trb_exeinfo();
static void trb_stackdump P_((unsigned long start, int nn, FILE **fp));
static void trb_framedump P_((unsigned long sp, unsigned long pc,
unsigned long fremeend, FILE **fp));
static void trb_getline P_((int nlevel));
static void trb_symbols P_((int ilevel, FILE fp, FILE fp2));
static void trb_traceback P_((int nlevel));
void trb_userinfo P_((FILE fp));
void trb_handle P_((int sig,int code,struct sigcontext *scp));
static void trb_sigtextinit();
static char *trb_codetext P_((int sig, int code));
static void trb_signal();
void trb_signalinit P_((int argc, char *argv[]));
static char *strstr();
/*----------------- structure definitions -----------------*/
struct levelstr
{unsigned long stackpointer;
unsigned long programcounter;
unsigned long frameend;
long fileaddr,funcaddr;
char funcname[256];
char filename[256];
int found;
int line;
int nparam;
};
struct exestr
{int nsym,nline,nstring;
unsigned long magic;
long stroffset;
long symoffset;
long lineoffset;
long textoffset;
char name[256];
};
/*----------------- global variables ----------------------*/
char sigtext[NSIGNAL+1][64];
struct levelstr level[MAXLEVEL];
struct exestr exe;
FILE *fpcrash,*fpstackdump,*fpframedump;
/* pointers to files CRASH, STACKDUMP, FRAMEDUMP */
/****************************************************************/
/* trb_exefind */
/* find the path of the file we are executing */
/****************************************************************/
void trb_exefind(argc,argv)
int argc;
char *argv[];
{
FILE *fp;
int ll;
char name[256],*path;
char *ptr,trial[256];
/*---------------------------------*/
/* get name of program */
strcpy(name,argv[0]);
/* 1: if name contains a slash, assume it is the direct path */
ptr= strchr(name,'/');
if(ptr!=NULL)
{strcpy(trial,name);
fp= fopen(trial,"r");
if(fp!=NULL)
{fclose(fp);strcpy(exe.name,trial);return;}
}
/* 2: look in the user's path */
ptr= getenv("PATH");
ll= strlen(ptr);
path= malloc(ll+1);
strcpy(path,ptr);
/* separate path string into its components */
ptr= strtok(path,":");
while(ptr!=NULL)
{strcpy(trial,ptr);
strcat(trial,"/");
strcat(trial,name);
DBPRINT(("trial exe is %s \n",trial));
fp= fopen(trial,"r");
if(fp!=NULL) {fclose(fp);strcpy(exe.name,trial);free(path);return;}
ptr= strtok(NULL,":");
}
/* 3: try the local directory in case it is not in the path */
strcpy(trial,"./");
strcat(trial,name);
DBPRINT(("trial exe is %s \n",trial));
fp= fopen(trial,"r");
if(fp!=NULL){fclose(fp);strcpy(exe.name,trial);return;}
} /* end of trb_exefind */
/****************************************************************/
/* trb_exeinfo */
/* get needed info from executable file header */
/****************************************************************/
void trb_exeinfo()
{
int i,j,k,ll,status,nline;
unsigned long magic;
FILE *fp,*fp2;
struct filehdr fheader; /* exe file header (from filehdr.h) */
struct aouthdr aheader; /* exe aux header (from aouthdr.h) */
struct scnhdr sheader; /* exe section header (from scnhdr.h) */
struct lineno linesym; /* line number entry (from linenum.h) */
struct syment symbol; /* symbols (from syms.h) */
AUXENT aux;
short fakeaux[9];
struct ldhdr lheader;
struct ldsym loadsym;
unsigned long hexdump,nseek,line,address,contents;
char *ptr,ttext[512],symbolname[80],funcname[80];
ulong toc;
/*--------------------*/
/* open exe file */
fp= fopen(exe.name,"r");
if(fp==NULL)
{printf("cant open %s\n",exe.name);
exit(1);}
fp2= fopen(exe.name,"r");
/* --------------------
read the file header
----------------------- */
status= fread(&fheader,FILHSZ,1,fp);
if(status==0) {printf("could not read file header\n"); exit(2);}
/* get the magic number */
exe.magic= fheader.f_magic;
/* how big is the symboltable header */
exe.nsym= fheader.f_nsyms;
DBPRINT(("nsym=%d\n",exe.nsym));
if(exe.nsym==0) exit(4);
/* get file offset for symboltable header */
exe.symoffset= fheader.f_symptr;
/* -------------------------------------------
read the auxillary header (we don't use it)
---------------------------------------------- */
status= fread(&aheader,sizeof(aheader),1,fp);
if(status==0) {printf("could not read aux header\n"); exit(2);}
/* --------------------------------------------------
read section headers to get offset to line numbers
----------------------------------------------------- */
i= 0;
strcpy(ttext," ");
while(i<8)
{status= fread(&sheader,SCNHSZ,1,fp);
if(status==0) {printf("could not read sec header\n"); exit(2);}
DBPRINT(("section header = %s size=%x offset=0x%x %d %o\n",
sheader.s_name, sheader.s_size, sheader.s_scnptr, sheader.s_scnptr,
sheader.s_scnptr));
if(strcmp(sheader.s_name,".text")==0)
{exe.nline= sheader.s_nlnno;
exe.textoffset= sheader.s_scnptr;
exe.lineoffset= sheader.s_lnnoptr; }
if(strcmp(sheader.s_name,".debug")==0)
exe.stroffset= sheader.s_scnptr;
i++;
}
#if 0
/* print all line numbers */
nseek= exe.lineoffset;
printf("line number nseek =%ld %o %x\n",nseek,nseek,nseek);
fseek(fp,nseek,0);
for(i=0;i<exe.nline;i++)
{status= fread(&linesym,LINESZ,1,fp);
if(status==0)printf("could not read line symbol %d\n",i);
line= linesym.l_lnno;
address= linesym.l_addr.l_paddr;
if(line!=0)
printf("linenum i=%d line#=%d addr=%x \n",i,line,address);
if(line==0)
{nseek= exe.symoffset+(address+3)*SYMESZ;
fseek(fp2,nseek,0);
status= fread(&symbol,SYMESZ,1,fp2);
if(symbol.n_zeroes==0)
{nseek= exe.stroffset + symbol.n_offset;
fseek(fp2,nseek,0); funcname[0]=CNULL;
ptr= fgets(funcname,80,fp2);
printf("%d %s \n",address,funcname);
}
else
printf("%d %s \n",address,symbol.n_name);
}
}
#endif
#if 0
/* print all symbols */
nseek= exe.symoffset;
printf("symbol table nseek =%ld %o %x\n",nseek,nseek,nseek);
fseek(fp,nseek,0);
for(i=0;i<exe.nsym;i++)
{status= fread(&symbol,SYMESZ,1,fp); /* sizeof(sym) wrong due to alignment */
if(status==0)printf("could not read symbol %d\n",i);
if(symbol.n_zeroes==0)
{nseek= exe.stroffset + symbol.n_offset;
fseek(fp2,nseek,0); symbolname[0]= CNULL;
ptr= fgets(symbolname,80,fp2);
printf("%s ((%d)) ",symbolname,i);
}
else
printf("%s (%d) ",symbol.n_name,i);
if(symbol.n_sclass==C_FUN)printf(" FUNCTION ");
else if(symbol.n_sclass==C_LSYM)printf(" local sym ");
else if(symbol.n_sclass==C_PSYM)printf(" parameter ");
else if(symbol.n_sclass==C_FCN)printf(" "); /* .bf or .ef */
else if(symbol.n_sclass==C_DECL)printf(" decl ");
else if(symbol.n_sclass==C_FILE)printf(" FILENAME ");
else if(symbol.n_sclass==C_HIDEXT)printf(" hidext ");
else printf(" sclass=%d ",symbol.n_sclass);
printf(" section=%d value=%d %x type=%x naux=%d\n",
symbol.n_scnum, symbol.n_value,symbol.n_value, symbol.n_type,
symbol.n_numaux);
if(symbol.n_numaux!=0)
{for(j=0;j<symbol.n_numaux;j++)
{
status= fread(fakeaux,AUXESZ,1,fp);
for(k=0;k<9;k++)printf("%4x",fakeaux[k]);
printf("\n");
i++;
}
}
}
#endif
fclose(fp);
fclose(fp2);
} /* end of trb_exeinfo */
/****************************************************************/
/* trb_stackdump */
/* dump the stack */
/****************************************************************/
static void trb_stackdump(start,nn,fp0)
unsigned long start;
int nn;
FILE **fp0;
{
int i,j;
FILE *fp;
/*------------------------------------------------------*/
/* start= 0x2003fa00; uncomment to dump the string area (ibm only) */
fp= *fp0;
if(fp==0)
{fp= fopen("STACKDUMP","a"); /* open for append */
if(fp==NULL) fp= stdout; /* if failure, use standard out */
*fp0= fp; /* save it in case we have two crashes */
}
trb_userinfo(fp);
for (i=0; i<nn;i++)
{fprintf(fp,"%08x ", (long)start);
fprintf(fp,"%08x ", *(unsigned long *)(start));
for(j=0;j<4;j++,start++)
fprintf(fp,"%c", isprint(*(unsigned char *)(start))
? *(unsigned char *)(start) : ' ');
fprintf(fp,"\n");
}
fclose(fp);
} /* end of trb_stackdump */
/****************************************************************/
/* trb_framedump */
/* dump a stack frame */
/****************************************************************/
static void trb_framedump(stackpointer,programcounter,frameend,fp0)
unsigned long stackpointer,programcounter,frameend;
FILE **fp0;
{
int j;
unsigned long stackaddress,stackvalue,pc2;
FILE *fp;
/*------------------------------------------------------*/
fp= *fp0;
if(fp==0)
{fp= fopen("FRAMEDUMP","a");
if(fp==NULL) fp= stdout;
trb_userinfo(fp);
*fp0= fp;
}
pc2= ibm_convert(programcounter);
fprintf(fp,"-----------------------------------\n");
fprintf(fp,"sp= %08x pc= %08x pc2= %08x\n",stackpointer,programcounter,pc2);
j= 0;
stackaddress= stackpointer;
while(stackaddress<frameend)
{stackvalue= *( (long *)stackaddress);
fprintf(fp," %8x",stackvalue);
j++;
if(j==8) {fprintf(fp,"\n");j= 0;}
stackaddress= stackaddress+4;
}
if(j!=0)fprintf(fp,"\n");
fprintf(fp,"-----------------------------------\n");
} /* end of trb_framedump */
/****************************************************************/
/* trb_getline */
/* find file lines matching addresses */
/****************************************************************/
void trb_getline(nlevel)
int nlevel;
{
struct lineno linesym; /* line number entry (from linenum.h) */
struct syment symbol; /* symbols (from syms.h) */
struct syment symbol2; /* symbols (from syms.h) */
AUXENT aux;
short fakeaux[9];
FILE *fp,*fp2;
unsigned long address,match,lastaddress;
unsigned long contents;
int type,line,funcsym,naux,lineadd;
int i,j,k,ll,il,ip,status;
long fileaddr,funcaddr,magic,nseek;
int iff,ii;
char *ptr,ttext[256];
char funcname[256],filename[256];
/*----------------------*/
/* initialize */
address= -1; funcsym= 0;
lastaddress= 0xFFFF;
for(i=0;i<MAXLEVEL;i++)level[i].found= 0;
DBPRINT(("in trb_getline: nlevel=%d pc[0]=%x\n",nlevel,level[0].programcounter));
/* use first file pointer to read symbol table */
fp= fopen(exe.name,"r");
if(fp==NULL){printf("cant open %s\n",exe.name);exit(1);}
/* use second file pointer to read the string table */
fp2= fopen(exe.name,"r");
/* search thru line numbers (in their own section) */
nseek= exe.lineoffset;
fseek(fp,nseek,0);
lineadd= 0;
for(i=0;i<exe.nline;i++)
{status= fread(&linesym,LINESZ,1,fp);
if(status==0)printf("could not read line symbol %d\n",i);
if(linesym.l_lnno!=0)
{line= linesym.l_lnno; address= linesym.l_addr.l_paddr;}
if(linesym.l_lnno==0) /* we are at the start of a function */
{funcsym= linesym.l_addr.l_paddr;
funcsym= funcsym+3;
nseek= exe.symoffset+ funcsym*SYMESZ; /* get the function's name */
fseek(fp2,nseek,0);
status= fread(&symbol,SYMESZ,1,fp2);
status= fread(&symbol2,SYMESZ,1,fp2); /* read .bf to get lineadd */
naux= symbol2.n_numaux;
if(naux>0)
{status= fread(fakeaux,AUXESZ,1,fp2);
lineadd= fakeaux[2]; /* x_sym.x_misc.x_lnsz.x_lnno */
}
/* get the name of the function */
if(symbol.n_zeroes==0)
{nseek= exe.stroffset + symbol.n_offset;
fseek(fp2,nseek,0); funcname[0]= CNULL;
ptr= fgets(funcname,80,fp2);
}
else
strcpy(funcname,symbol.n_name);
ptr= strchr(funcname,':');
if(ptr!=NULL) *ptr= CNULL;
}
/* does this address match one of ours? */
for(iff=0;iff<nlevel;iff++)
{if(level[iff].found==0)
{match= level[iff].programcounter;
if(address==match)
{DBPRINT(("exact match of %x found at line %d\n",match,line));
level[iff].found= funcsym;
strcpy(level[iff].funcname,funcname);
strcpy(level[iff].filename," ");
level[iff].line= line+lineadd;
}
else if(address>match && lastaddress<match && lastaddress>(match-64))
{
DBPRINT(("match of %x before line %d, lastaddress=%x address=%x\n",
match,line,lastaddress,address));
level[iff].found= funcsym;
strcpy(level[iff].funcname,funcname);
strcpy(level[iff].filename," ");
level[iff].line= line-1+lineadd;
}
}
}
lastaddress= address;
} /* end of loop over nline */
/* now find the file names */
nseek= exe.symoffset;
fseek(fp,nseek,0);
strcpy(filename,"");
for(i=0;i<exe.nsym;i++)
{status= fread(&symbol,SYMESZ,1,fp);
if(status==0)printf("could not read symbol %d\n",i);
if(symbol.n_sclass==C_FILE)
{if(symbol.n_zeroes==0)
{nseek= exe.stroffset + symbol.n_offset;
fseek(fp2,nseek,0); filename[0]= CNULL;
ptr= fgets(filename,80,fp2);
}
else
strcpy(filename,symbol.n_name);
}
for(iff=0;iff<nlevel;iff++)
{if(level[iff].found==i)
strcpy(level[iff].filename,filename);
}
}
fclose(fp);
fclose(fp2);
} /* end of trb_getline */
/****************************************************************/
/* trb_params */
/* print one level of parameters */
/****************************************************************/
void trb_params(ilevel,fp,fp2)
int ilevel;
FILE *fp, *fp2;
{
struct syment symbol; /* symbols (from syms.h) */
AUXENT aux;
int i,j,ll,status,isym,naux,nparam;
long nseek,address,stackbase,off,contents;
char *ptr,symbolname[80],symboltype[80];
char params[1024];
char values[MAXPARAM][80];
/*------------------------------------*/
strcpy(params,level[ilevel].funcname);
strcat(params,"(");
nparam= 0;
isym= level[ilevel].found;
nseek= exe.symoffset + isym*SYMESZ;
fseek(fp,nseek,0);
for(i=isym;i<exe.nsym;i++)
{status=fread(&symbol,SYMESZ,1,fp); /* sizeof(sym) wrong due to alignment */
if(status==0)printf("could not read symbol %d\n",i);
naux= symbol.n_numaux;
if(symbol.n_sclass==C_FCN) /* .bf or .ef */
if(STREQ(symbol.n_name,".ef"))goto print;
if(symbol.n_sclass==C_PSYM) /* a parameter */
{if(symbol.n_zeroes==0)
{nseek= exe.stroffset + symbol.n_offset;
fseek(fp2,nseek,0); symbolname[0]= CNULL;
ptr= fgets(symbolname,80,fp2);
}
else
strcpy(symbolname,symbol.n_name);
ptr= strchr(symbolname,':');
if(ptr!=NULL)
{strcpy(symboltype,ptr); *ptr= CNULL;}
else symboltype[0]= CNULL;
strcat(params,symbolname); strcat(params,",");
off= symbol.n_value;
stackbase= level[ilevel].stackpointer;
address= stackbase + off;
ptr= *(long *)address;
if(STREQ(symboltype,":p2"))
sprintf(values[nparam]," %s = \"%s\" ",symbolname,ptr);
else if(STREQ(symboltype,":p-1"))
sprintf(values[nparam]," %s = %d 0x%x (long)",
symbolname,*(long *)address,*(long *)address);
else if(STREQ(symboltype,":p-3"))
sprintf(values[nparam]," %s = %d 0x%x (short)",
symbolname,*(short *)address,*(short *)address);
else if(STREQ(symboltype,":p-12"))
sprintf(values[nparam]," %s = %f (float)",symbolname,
*(float *)address);
else if(STREQ(symboltype,":p-13"))
sprintf(values[nparam]," %s = %f (double)",symbolname,
*(double *)address);
else
sprintf(values[nparam]," %s unknown type [%s]",
symbolname, symboltype);
nparam++;
}
if(naux>0)
for(j=0;j<naux;j++) status= fread(&aux,AUXESZ,1,fp);
} /* end of loop over isym */
print:
/* change the last comma to an ) */
ll= strlen(params);
if(params[ll-1]==',') params[ll-1]= ')'; else strcat(params,")");
fprintf(fpcrash,"%s\n",params);
for(i=0;i<nparam;i++)fprintf(fpcrash,"%s\n",values[i]);
} /* end of trb_params */
/****************************************************************/
/* trb_symbols */
/* print local symbols in procedure of interest */
/****************************************************************/
void trb_symbols(ilevel,fp,fp2)
int ilevel;
FILE *fp, *fp2;
{
struct syment symbol; /* symbols (from syms.h) */
AUXENT aux;
int i,j,ll,status,isym,naux,nparam;
long nseek,address,stackbase,off;
unsigned long dead,live;
char *ptr,symbolname[80],symboltype[16];
char ttext[512];
short int jtemp; unsigned short jtemp2;
int itemp;
float ftemp;
double dtemp;
/*-----------------------------------*/
dead= 0xdeadbeef;
fprintf(fpcrash,"%s \n",level[ilevel].funcname);
isym= level[ilevel].found;
nseek= exe.symoffset + isym*SYMESZ;
fseek(fp,nseek,0);
for(i=isym;i<exe.nsym;i++)
{status= fread(&symbol,SYMESZ,1,fp); /* sizeof(sym) wrong due to alignment */
if(status==0)printf("could not read symbol %d\n",i);
naux= symbol.n_numaux;
if(symbol.n_sclass==C_FCN) /* .bf or .ef */
if(STREQ(symbol.n_name,".ef"))return;
if(symbol.n_sclass==C_LSYM)
{if(symbol.n_zeroes==0)
{nseek= exe.stroffset + symbol.n_offset;
fseek(fp2,nseek,0); symbolname[0]= CNULL;
ptr= fgets(symbolname,80,fp2);
}
else
strcpy(symbolname,symbol.n_name);
ptr= strchr(symbolname,':');
if(ptr!=NULL)
{strcpy(symboltype,ptr); *ptr= CNULL;}
else symboltype[0]= CNULL;
off= symbol.n_value;
stackbase= level[ilevel].stackpointer;
address= stackbase + off;
live= *(long *)address;
if(live == dead)
fprintf(fpcrash," %s is unassigned \n",symbolname);
else if(STREQ(symboltype,":2"))
fprintf(fpcrash," %s = \"%s\" (ptr) \n",symbolname,(char *)address);
else if(STREQ(symboltype,":3"))
fprintf(fpcrash," %s = \"%s\" \n",symbolname,(char *)address);
else if(STREQ(symboltype,":4"))
fprintf(fpcrash," %s = \"%s\" \n",symbolname,(char *)address);
else if(STREQ(symboltype,":-1"))
fprintf(fpcrash," %s = %d 0x%x (long) \n",
symbolname,*(long *)address,*(long *)address);
else if(STREQ(symboltype,":-3"))
fprintf(fpcrash," %s = %d 0x%x (short) \n",
symbolname,*(short *)address,*(short *)address);
else if(STREQ(symboltype,":-12"))
fprintf(fpcrash," %s = %f 0x%x (float) \n",
symbolname,*(float *)address,*(float *)address);
else if(STREQ(symboltype,":-13"))
fprintf(fpcrash," %s = %f 0x%x (double) \n",
symbolname,*(double *)address,*(double *)address);
else
fprintf(fpcrash," %s unknown type [%s] \n",
symbolname, symbol.n_value,symbol.n_value, symboltype);
}
if(naux>0)
for(j=0;j<naux;j++) status= fread(&aux,AUXESZ,1,fp);
} /* end of loop over isym */
} /* end of trb_symbols */
/****************************************************************/
/* trb_traceback */
/* print a traceback */
/****************************************************************/
void trb_traceback(nlevel)
int nlevel;
{
int i;
FILE *fp,*fp2;
/*---------------------------*/
if(nlevel<1)return;
/* use first file pointer to read the symbol table */
fp= fopen(exe.name,"r");
if(fp==NULL){printf("cant open %s\n",exe.name);exit(1);}
/* use second file pointer to read the string table */
fp2= fopen(exe.name,"r");
/* print a traceback to the screen */
fprintf(fpcrash,"---------- traceback ----------\n");
for(i=0;i<nlevel;i++)
{if(level[i].found!=0)
fprintf(fpcrash,"file %s\t line %d\t function %s() \n",
level[i].filename, level[i].line, level[i].funcname);
else
fprintf(fpcrash,"address %x \n", level[i].programcounter);
}
fprintf(fpcrash,"---------- parameters ----------\n");
for(i=0;i<nlevel;i++)
if(level[i].found!=0) trb_params(i,fp,fp2);
fprintf(fpcrash,"---------- local symbols ----------\n");
for(i=0;i<nlevel;i++)
if(level[i].found!=0) trb_symbols(i,fp,fp2);
fclose(fp2);
fclose(fp);
} /* end of trb_traceback */
/****************************************************************/
/* ibm_convert */
/* convert stack addresses to coff addresses */
/****************************************************************/
long ibm_convert(stack)
long stack;
{
long coff;
static int first=1;
if(first==1)
{coff= PCADJUST;
DBPRINT(("pcadjust= %d 0x%x \n",coff,coff));
first=0;
}
if(stack>PCADJUST) coff= stack-PCADJUST;
else coff= stack;
return(coff);
} /* end of ibm_convert */
/****************************************************************/
/* trb_userinfo */
/* put program name, user, etc into CRASH */
/****************************************************************/
void trb_userinfo(fp)
FILE *fp;
{
int ll;
char *user,host[64],nouser[8];
time_t timeofday;
char fulltime[26];
/* get the user's name */
user= (char *) getlogin();
if(user==NULL)user= (char *)getpwuid(getuid());
if(user==NULL){strcpy(nouser,"????"); user=nouser; }
/* get the time */
timeofday=time((time_t *)0);
strcpy(fulltime,ctime(&timeofday));
fulltime[24]=CNULL;
/* get the host */
gethostname(host,64);
/* write to CRASH */
fprintf(fp,"user=%s host=%s date=%s \n", user,host,fulltime);
fprintf(fp,"program=%s \n", exe.name);
} /* end of trb_userinfo */
/****************************************************************/
/* trb_handle */
/* handle all signals */
/****************************************************************/
void trb_handle(sig,code,scp)
int sig, code;
struct sigcontext *scp;
{
int i,j,exitflag;
int nlevel;
int freg,pcreg;
unsigned long programcounter,stackpointer,frameend,pc2;
unsigned long inst;
unsigned long toc,toc2,link;
unsigned long as[16],asa;
char *ptr;
char *startdump;
/*--------------------*/
#if 0 /* set to 1 to dump all general registers */
for(i=0;i<NGPRS;i++)
printf(" gpr[%d] 0x%08x \n",i,(*scp).sc_jmpbuf.jmp_context.gpr[i]);
#endif
/* write to a file called CRASH */
if(fpcrash==0)fpcrash= fopen("CRASH","a"); /* open for append */
if(fpcrash==NULL) fpcrash= stdout; /* write to standard output */
fprintf(fpcrash,"vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
trb_userinfo(fpcrash);
/* print meaningful message for signal */
fprintf(fpcrash,"%s signal=%d(%d) \n",sigtext[sig],sig,code);
ptr= trb_codetext(sig,code);
if(ptr!=NULL) fprintf(fpcrash,"%s\n",ptr);
/* get stack pointer & program counter */
programcounter= (*scp).sc_jmpbuf.jmp_context.iar; /* from dbx registers */
stackpointer= (*scp).sc_jmpbuf.jmp_context.gpr[1];
frameend= *( (long *)stackpointer +JUMPSP);
pc2= ibm_convert(programcounter);
DBPRINT((" pc=0x%x sp=0x%x pc2=0x%x\n", programcounter,stackpointer,pc2));
#if 0 /* set to 1 to look at other values regards PCADJUST */
toc= (*scp).sc_jmpbuf.jmp_context.gpr[2];
toc2= *(long *)toc;
link= (*scp).sc_jmpbuf.jmp_context.lr;
printf("toc=%x toc2=%x link=%x \n",toc,toc2,link);
asa= (*scp).sc_jmpbuf.jmp_context.as.alloc;
printf("as.alloc=%d %x \n",asa,asa);
for(i=0;i<16;i++)
{as[i]= (*scp).sc_jmpbuf.jmp_context.as.srval[i];
printf("as.srval[%d]= %d %x\n",i,as[i],as[i]);
}
#endif
#if STACKDUMP
startdump= (char *) stackpointer;
startdump= startdump-16;
trb_stackdump(startdump,DUMPSIZE,&fpstackdump);
#endif
/* trace the stack & store stack pointers & program counters */
nlevel= 0;
while(stackpointer!= 0)
{level[nlevel].programcounter= pc2;
level[nlevel].frameend= 0;
level[nlevel].stackpointer= stackpointer;
if(nlevel<MAXLEVEL)nlevel++;
#if FRAMEDUMP
trb_framedump(stackpointer,programcounter,frameend,&fpframedump);
#endif
stackpointer= *( (long *)stackpointer +JUMPSP);
if(stackpointer!=0) frameend= *( (long *)stackpointer +JUMPSP);
programcounter= *( (long *)stackpointer +JUMPPC);
pc2= ibm_convert(programcounter);
if(frameend==0) stackpointer= 0;
}
trb_exeinfo(); /* get info from file header */
trb_getline(nlevel); /* convert addresses to line numbers */
trb_traceback(nlevel); /* print a full traceback */
exitflag= 0;
switch(sig)
{case SIGTRAP: exitflag= 1; break;
case SIGSEGV: exitflag= 1; break;
case SIGBUS: exitflag= 1; break;
case SIGILL: exitflag= 1; break;
case SIGFPE: exitflag= 1; break;
default: break;
} /* end of switch on sig */
fprintf(fpcrash,"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
#if FRAMEDUMP
fclose(fpframedump);
#endif
if(exitflag)
{if(fpcrash!=stdout)
{fclose(fpcrash);
/* system("ls -l CRASH"); */
}
exit(sig);
}
return;
} /* end of trb_handle */
/****************************************************************/
/* trb_sigtextinit */
/* initialize signal text messages */
/****************************************************************/
void trb_sigtextinit()
{
strcpy(sigtext[1], "SIGHUP: hangup signal received");
strcpy(sigtext[2], "SIGINT: interrupt signal received");
strcpy(sigtext[3], "SIGQUIT: quit signal received");
strcpy(sigtext[4], "SIGILL: illegal instruction (not reset when caught)");
strcpy(sigtext[5], "SIGTRAP: trace trap (not reset when caught)");
strcpy(sigtext[6], "SIGIOT: IOT instruction");
strcpy(sigtext[7], "SIGEMT: EMT instruction");
strcpy(sigtext[8], "SIGFPE: floating point exception");
strcpy(sigtext[9], "SIGKILL: kill signal received");
strcpy(sigtext[10], "SIGBUS: bus error");
strcpy(sigtext[11], "SIGSEGV: segmentation violation");
strcpy(sigtext[12], "SIGSYS: bad argument to system call");
strcpy(sigtext[13], "SIGPIPE: write on a pipe with no one to read it");
strcpy(sigtext[14], "SIGALRM: alarm clock signal received");
strcpy(sigtext[15], "SIGTERM: received software termination signal");
strcpy(sigtext[16], "SIGURG: urgent condition on IO channel");
strcpy(sigtext[17], "SIGSTOP: sendable stop signal not from tty");
strcpy(sigtext[18], "SIGTSTP: received stop signal from tty");
strcpy(sigtext[19], "SIGCONT: continue a stopped process");
strcpy(sigtext[20], "SIGCHLD: child process has stopped or exited");
strcpy(sigtext[21], "SIGTTIN: to readers pgrp upon background tty read");
strcpy(sigtext[22], "SIGTTOU: like TTIN for output if (tp->t_local<OSTOP)");
strcpy(sigtext[23], "SIGIO: input/output possible signal");
strcpy(sigtext[24], "SIGXCPU: exceeded CPU time limit");
strcpy(sigtext[25], "SIGXFSZ: exceeded file size limit");
strcpy(sigtext[26], "SIGVTALRM: received virtual time alarm");
strcpy(sigtext[27], "SIGPROF: received profiling time alarm");
strcpy(sigtext[28], "SIGWINCH: window changed");
strcpy(sigtext[30], "SIGUSR1: received user defined signal 1");
strcpy(sigtext[31], "SIGUSR2: received user defined signal 2");
} /* end if trb_sigtextinit */
/****************************************************************/
/* trb_codetext */
/* initialize code text messages */
/****************************************************************/
char *trb_codetext(sig,code)
int sig,code;
{
return(NULL);
} /* end of trb_codetext */
/****************************************************************/
/* trb_signal */
/* initiate trapping of all signals */
/****************************************************************/
void trb_signal()
{
int status;
/*---------------------------------------*/
trb_sigtextinit();
/* trap important signals */
signal(SIGFPE,trb_handle);
signal(SIGBUS,trb_handle);
signal(SIGSEGV,trb_handle);
signal(SIGILL,trb_handle);
signal(SIGTRAP,trb_handle);
signal(SIGIOT,trb_handle);
#if 0
signal(SIGHUP,trb_handle);
signal(SIGINT,trb_handle);
signal(SIGQUIT,trb_handle);
signal(SIGEMT,trb_handle);
signal(SIGSYS,trb_handle);
signal(SIGPIPE,trb_handle);
signal(SIGALRM,trb_handle);
signal(SIGTERM,trb_handle);
signal(SIGURG,trb_handle);
signal(SIGSTOP,trb_handle);
signal(SIGTSTP,trb_handle);
signal(SIGCONT,trb_handle);
signal(SIGCHLD,trb_handle);
signal(SIGTTIN,trb_handle);
signal(SIGTTOU,trb_handle);
signal(SIGIO,trb_handle);
signal(SIGXCPU,trb_handle);
signal(SIGXFSZ,trb_handle);
signal(SIGVTALRM,trb_handle);
signal(SIGPROF,trb_handle);
#endif
} /* end of trb_signal */
/****************************************************************/
/* ita_signalinit */
/* initiate trapping of all signals */
/****************************************************************/
void ita_signalinit(argc,argv)
int argc;
char *argv[];
{
FILE *fp;
/*---------------------------------------*/
trb_exefind(argc,argv);
fp= fopen("CRASH","w");
if(fp!=NULL) fclose(fp); /* remove file called CRASH */
fpcrash= 0;
fp= fopen("STACKDUMP","w");
if(fp!=NULL) fclose(fp); /* remove file called STACKDUMP */
fpstackdump= 0;
fpstackdump= 0;
fp= fopen("FRAMEDUMP","w");
if(fp!=NULL) fclose(fp); /* remove file called FRAMEDUMP */
fpframedump= 0;
trb_signal();
} /* end of ita_signalinit */